#ifndef IO_HEADER
#define IO_HEADER
#include<string>
#include<fstream>
#include<sstream>
#include<iostream>
#include<algorithm>
#include<iterator>
#include<vector>
#include<map>
#include<cstdlib>
#include<ctime>
#include<cmath>
#include "def.hpp"
#include "utils.hpp"

using namespace std;
namespace Puza{
  int ReadDOCS(DocList& assignment,int&,int,int); // the first argument is the document containers, the second argument is the read mode
  int ReadDOCS_Batch(DocList& assignment, int&, int);
  int ReadDOCS_Online(DocList& assignment, int&, int);
  
  template <class T>
  int ReadData(T**& buffer){
    ifstream inFile;
    string original_id;
    string temp;
    inFile.open(PuzaDEF::Instance()->input_file_name.c_str());
    PuzaDEF::Instance()->data_ids.clear();
    while(!inFile.eof()){
      getline(inFile,temp,'\n');
      std::istringstream iss(temp);
      getline(iss,temp,'\t');
      original_id = temp;
      //    cout << original_id << endl;
      // get the doc body
      getline(iss,temp,'\n');
      std::istringstream tempiss(temp);
      vector<string> tokens;
      copy(istream_iterator<string>(tempiss), istream_iterator<string>(), back_inserter<vector<string> >(tokens));
      if(tokens.size()<1){
	continue;
      }
      int now_id = PuzaDEF::Instance()->data_ids.size();
      PuzaDEF::Instance()->data_ids[now_id] = original_id;
      for (vector<string>::iterator iter = tokens.begin(); iter < tokens.end(); iter++){
	int dim_id;
	T dim_value;
	std::istringstream valueiss((*iter));
	getline(valueiss,temp,':');
	from_string<int>(dim_id,temp,std::dec);
	getline(valueiss,temp);  // get count
	from_string<T>(dim_value,temp,std::dec);
	buffer[now_id][dim_id] = dim_value;
      }
    }  
    inFile.close();
    return 0;
  }
};

#endif
